home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
001-100
/
001-025
/
004
/
kermit
/
receive.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-17
|
5KB
|
259 lines
/* @(#)receive.c 1.1 1/26/85 */
/*
* receive - routines for receiving data
*
* r e c s w
*/
#include "kermit.h"
#include "errors.h"
static char rinit ();
static char rfile ();
static char rdata ();
VOID Receive ()
{
DBUG_ENTER ("receive");
DBUG_2 ("rec", "begin receive attempt");
if (recsw () == FALSE) {
(VOID) printf ("Receive failed.\n");
} else {
(VOID) printf ("OK\n");
}
DBUG_VOID_RETURN;
}
recsw ()
{
DBUG_ENTER ("recsw");
DBUG_2 ("init", "initializing receive variables");
state = 'R'; /* receive is the start state */
n = 0; /* initialize message number */
numtry = 0; /* say no tries yet */
while (TRUE) { /* do this as long as necessary */
DBUG_3 ("states", "state %c found", state);
switch (state) {
case 'D':
state = rdata ();
break; /* data receive state */
case 'F':
state = rfile ();
break; /* fil receive state */
case 'R':
state = rinit ();
break; /* send initiate state */
case 'C':
DBUG_RETURN (TRUE); /* complte state */
case 'A':
DBUG_RETURN (FALSE); /* unknown state, abort */
}
}
}
/*
* r i n i t
*/
static char rinit ()
{
auto int len;
auto int num;
register char newstate;
DBUG_ENTER ("rinit");
if (numtry++ > MAXTRY) {
newstate = 'A';
} else {
DBUG_2 ("state", "begin receive init");
switch (rpack (&len, &num, packet)) {
case 'S': /* send-init */
DBUG_2 ("init", "got S packet");
rpar (packet); /* get the init data */
spar (packet); /* fill up packet with init info */
spack ('Y', n, 6, packet); /* ACK with my parameters */
oldtry = numtry;
numtry = 0; /* and start a new counter */
n = (n + 1) % 64; /* bump packet number */
newstate = 'F';
break;
case FALSE:
DBUG_2 ("init", "no S packet");
newstate = state;
break;
default:
newstate = 'A';
break;
}
}
DBUG_3 ("states", "new state %c", newstate);
DBUG_RETURN (newstate);
}
/*
* r f i l e
*/
static char rfile ()
{
auto int num;
auto int len;
char *bp;
register char newstate;
DBUG_ENTER ("rfile");
if (numtry++ > MAXTRY) {
DBUG_3 ("tries", "%d tries", numtry - 1);
newstate = 'A';
} else {
switch (rpack (&len, &num, packet)) {
case 'S':
DBUG_2 ("S", "got S packet");
if (oldtry++ > MAXTRY) {
newstate = 'A';
} else if (num == n - 1) {
spar (packet);
spack ('Y', num, 6, packet);
numtry = 0;
newstate = state;
} else {
newstate = 'A';
}
break;
case 'Z': /* end-of-file */
if (oldtry++ > MAXTRY) {
newstate = 'A';
} else if (num == n - 1) { /* acknowledge good packet */
spack ('Y', num, 0, packet);
numtry = 0;
newstate = state;
} else {
newstate = 'A';
}
break;
case 'F': /* file-header */
if (num != n) {
newstate = 'A';
break;
}
DBUG_3 ("pack", "converting %s", packet);
if (mflg) {
for (bp = &packet[0]; *bp != NULL; bp++) {
*bp = tolower(*bp);
}
}
DBUG_3 ("files", "open file %s", packet);
if (!getfil (packet)) {
Error (RCVFILE, packet);
newstate = 'A';
} else {
if (host) {
(VOID) printf ("Receiving %s\n", packet);
}
spack ('Y', n, 0, packet); /* acknowledge */
oldtry = numtry;
numtry = 0;
n = (n + 1) % 64;
newstate = 'D';
}
break;
case 'B':
if (num != n) {
newstate = 'A';
} else {
spack ('Y', n, 0, packet);
newstate = 'C';
}
break;
case FALSE:
newstate = state;
break;
default:
newstate = 'A';
break;
}
}
DBUG_3 ("states", "new state %c", newstate);
DBUG_RETURN (newstate);
}
/*
* r d a t a
*/
static char rdata ()
{
auto int num;
auto int len;
register char newstate;
DBUG_ENTER ("rdata");
DBUG_2 ("rcv", "receive data");
if (numtry++ > MAXTRY) {
newstate = 'A';
} else {
switch (rpack (&len, &num, packet)) { /* get packet */
case 'D': /* data */
DBUG_2 ("rcv", "got D packet");
DBUG_3 ("rcv", "length %d", len);
if (num != n) { /* right packet? */
if (oldtry++ > MAXTRY) {
newstate = 'A';
} else if (num == n - 1) {
spar (packet);
spack ('Y', num, 6, packet);
numtry = 0;
newstate = state;
} else {
newstate = 'A';
}
} else {
bufemp (packet, fd, len);
spack ('Y', n, 0, packet);
oldtry = numtry;
numtry = 0;
n = (n + 1) % 64;
newstate = 'D';
}
break;
case 'F': /* file-send */
DBUG_2 ("rcv", "got F packet");
if (oldtry++ > MAXTRY) {
newstate = 'A';
} else if (num == n - 1) { /* ack good packet */
spack ('Y', num, 0, packet);
numtry = 0;
newstate = state;
} else {
newstate = 'A';
}
break;
case 'Z': /* end-of-file */
DBUG_2 ("rcv", "got Z packet");
if (num != n) {
newstate = 'A';
} else {
spack ('Y', n, 0, packet); /* say OK */
(VOID) close (fd); /* close up file */
n = (n + 1) % 64;
newstate = 'F';
}
break;
case FALSE:
newstate = state;
break;
default:
newstate = 'A';
break;
}
}
DBUG_3 ("states", "new state %c", newstate);
DBUG_RETURN (newstate);
}